过渡动画使 UI 更富有表现力并且易于使用。如何使用 React 快速的实现一个 Transition 过渡动画组件?
基本实现
实现一个基础的 CSS 过渡动画组件,通过切换 CSS 样式实现简单的动画效果,也就是通过添加或移除某个 class 样式。因此需要给 Transition 组件添加一个 toggleClass 属性,标识要切换的 class 样式,再添加一个 action 属性实现样式切换,action 为 true 时添加 toggleClass 到动画元素上,action 为 false 时移除 toggleClass。
安装 classnames 插件:
1 | npm install classnames --save-dev |
classnames 是一个简单的JavaScript实用程序,用于有条件地将 className 连接在一起。
在 components 目录下新建一个 Transition 文件夹,并在该文件夹下新建一个 Transition.jsx 文件:
1 | import React from 'react' |
这里使用了 JSX,在 JSX 中,使用 camelCase(小驼峰命名)来定义属性的名称,使用大括号“{}”嵌入任何有效的 JavaScript 表达式。
如:
1 | const name = 'Josh Perez'; |
等价于:
1 | const element = <h1>Hello, Josh Perez</h1>; |
注意:
因为 JSX 语法上更接近 JavaScript 而不是 HTML,所以 React DOM 使用 camelCase(小驼峰命名)来定义属性的名称,而不使用 HTML 属性名称的命名约定。
例如,JSX 里的 class 变成了 className,而 tabindex 则变为 tabIndex。
另外,在 React 中,props.children
包含组件所有的子节点,即组件的开始标签和结束标签之间的内容(与 Vue 中 slot 插槽相似)。例如:
1 | <Button>默认按钮</Button> |
在 Button 组件中获取 props.children,就可以得到字符串“默认按钮”。
接下来,在 Transition 文件夹下新建一个 index.js,导出 Transition 组件:
1 | import Transition from './Transition.jsx' |
然后,在 Transition.jsx 文件中为组件添加 props 检查并设置 action 的默认值:
1 | import PropTypes from 'prop-types' |
这里使用了 prop-types 实现运行时类型检查。
注意:
prop-types 是一个运行时类型检查工具,也是 create-react-app 脚手架默认配置的运行时类型检查工具,使用时直接引入即可,无需安装。
完整的 Transition 组件代码如下:
1 | import React from 'react' |
现在,可以使用我们的 Transition 组件了。
CSS 代码如下:
1 | .fade { |
JS 代码如下:
1 | import React from 'react'; |
然后,在你需要该动画的地方使用 Anime 组件即可。
实现 Animate.css 兼容
Animate.css 是一款强大的预设 CSS3 动画库。接下来,实现在 Transition 组件中使用 Animate.css 实现强大的 CSS3 动画。
由于 Animate.css 动画在进入动画和离开动画通常使用两个效果相反的 class 样式,因此,需要给 Transition 组件添加 enterClass 和 leaveClass 两个属性,实现动画切换。
1 | import React from 'react' |
注意:
由于 toggleClass 适用于那些进入动画与离开动画切换相同 class 样式的情况,而 enterClass 和 leaveClass 适用于那些进入动画与离开动画切换不同的 class 样式的情况,所以,他们与 toggleClass 不能共存。
接下来,就可以试一试加入 Animate.css 后的 Transition 组件:
1 | import React from 'react'; |
功能扩展
通过上面的实现,Transition 组件能适用大部分场景,但是功能不够丰富。因此,接下来就需要扩展 Transition 的接口。动画通常可以设置延迟时间,播放时长,播放次数等属性。因此,需要给 Transition 添加这些属性,来丰富设置动画。
添加如下 props 属性,并设置默认值:
1 | const propTypes = { |
根据 props 设置样式:
1 | // 动画样式 |
完整代码如下:
1 | import React from 'react' |
这里为 Transition 增加了以下设置属性:
- delay:规定在动画开始之前的延迟。
- duration:规定完成动画所花费的时间,以秒或毫秒计。
- count:规定动画应该播放的次数。
- easing:规定动画的速度曲线。
- reverse:规定是否应该轮流反向播放动画。
目前,Transition 的功能已经相当丰富,可以很精细的控制 CSS3 动画。
优化
这一步,我们需要针对 Transition 组件进一步优化,主要包括动画结束的监听、卸载组件以及兼容。
添加以下 props 属性,并设置默认值:
1 | const propTypes = { |
处理动画结束的监听事件:
1 | /** |
这里使用到两个生命周期函数 componentDidMount 和 componentWillUnmount,关于 React 生命周期的介绍请移步组件生命周期。
react-dom 提供了可在 React 应用中使用的 DOM 方法。
获取兼容性的 animationend 事件和 transitionend 事件。不同的浏览器要求使用不同的前缀,因为火狐和IE都已经支持了这两个事件,因此,只需针对 webkit 内核浏览器进行兼容的 webkitTransitionEnd 事件检测。检测函数代码如下:
1 | /** |
修改 handleEndListener 函数:
1 | /** |
到这里,我们完成了整个 Transition 组件的开发,完整代码如下:
1 | import React from 'react' |